#include <check.h>
#include <imbus.h>
#include <stdio.h>
#include <string.h>

static const IMChar *demo1 = "Hello world";
static const IMChar *demo2 = "Hello world-------------------";
static const IMChar *demo3 = "blablabla";
static const IMChar *demo4 = "blablablaHello world";
static const IMChar *demo5 = "blablablaHello worldblablabla";

START_TEST(string_new)
{
    IMString *str;
    str = im_string_new (demo1);
    fail_if (str == NULL, NULL);
    fail_if (im_string_empty (str), NULL);
    fail_if (im_string_length (str) != strlen (demo1), NULL);
    fail_if (strcmp (im_string_c_str (str), demo1) != 0, NULL);
    im_object_unref (str);
}
END_TEST

START_TEST(string_new_static)
{
    IMString *str;
    str = im_string_new_static (demo1);
    fail_if (str == NULL, NULL);
    fail_if (im_string_empty (str), NULL);
    fail_if (im_string_length (str) != strlen (demo1), NULL);
    fail_if (im_string_c_str (str) != demo1, NULL);
    im_object_unref (str);
}
END_TEST

START_TEST(string_new_length)
{
    IMString *str;
    str = im_string_new_length (demo1, 5);
    fail_if (str == NULL, NULL);
    fail_if (im_string_empty (str), NULL);
    fail_if (im_string_length (str) != 5, NULL);
    fail_if (strncmp (im_string_c_str (str), demo1, 5) != 0, NULL);
    im_object_unref (str);
}
END_TEST

START_TEST(string_new_reserved)
{
    IMString *str;
    str = im_string_new_reserved (10);
    fail_if (str == NULL, NULL);
    fail_unless (im_string_empty (str), NULL);
    fail_if (im_string_length (str) != 0, NULL);
    fail_if (im_string_capacity (str) != 10, NULL);
    im_object_unref (str);
}
END_TEST

START_TEST(string_new_from_printf)
{
    IMString *str;
    str = im_string_new_from_printf ("%s", demo1);
    fail_if (str == NULL, NULL);
    fail_if (im_string_empty (str), NULL);
    fail_if (im_string_length (str) != strlen (demo1), NULL);
    fail_if (strcmp (im_string_c_str (str), demo1) != 0, NULL);
    im_object_unref (str);
}
END_TEST

START_TEST(string_miscs)
{
    IMString *str;
    str = im_string_new (demo1);
    fail_if (str == NULL, NULL);
    fail_if (im_string_empty (str), NULL);
    fail_if (im_string_length (str) != strlen (demo1), NULL);
    fail_if (strcmp (im_string_c_str (str), demo1) != 0, NULL);
    im_string_resize (str, 30, '-');
    fail_if (im_string_length (str) != 30, NULL);
    fail_if (strcmp (im_string_c_str (str), demo2) != 0, NULL);
    im_string_clear (str);
    fail_if (im_string_length (str) != 0, NULL);
    im_object_unref (str);
}
END_TEST

START_TEST(string_assign)
{
    IMString *str;
    str = im_string_new (0);
    fail_if (str == NULL, NULL);
    fail_if (im_string_length (str) != 0, NULL);
    im_string_assign (str, demo1, 5);
    fail_if (im_string_length (str) != 5, NULL);
    fail_if (strncmp (im_string_c_str (str), demo1, 5) != 0, NULL);
    im_string_assign (str, demo2, -1);
    fail_if (im_string_length (str) != strlen (demo2), NULL);
    fail_if (strcmp (im_string_c_str (str), demo2) != 0, NULL);
    im_string_assign_static (str, demo1);
    fail_if (im_string_length (str) != strlen (demo1), NULL);
    fail_if (strcmp (im_string_c_str (str), demo1) != 0, NULL);
    im_string_resize (str, 5, 0);
    fail_if (im_string_length (str) != 5, NULL);
    fail_if (strncmp (im_string_c_str (str), demo1, 5) != 0, NULL);
    im_object_unref (str);
}
END_TEST

START_TEST(string_modification)
{
    IMString *str;
    IMString *other;
    str = im_string_new (demo1);
    fail_if (im_string_get_char (str, 0) != demo1[0], NULL);
    fail_if (im_string_get_char (str, 10) != demo1[10], NULL);
    im_string_set_char (str, 5, '-');
    fail_if (im_string_get_char (str, 5) != '-', NULL);
    im_string_set_char (str, 5, demo1[5]);
    other = im_string_new_static (demo3);
    fail_if (im_string_prepend (str, other) != str, NULL);
    fail_if (strcmp (im_string_c_str (str), demo4) != 0, NULL);
    fail_if (im_string_append (str, other) != str, NULL);
    fail_if (strcmp (im_string_c_str (str), demo5) != 0, NULL);
    im_string_assign (str, demo1, -1);
    fail_if (im_string_prepend_str (str, demo3, -1) != str, NULL);
    fail_if (strcmp (im_string_c_str (str), demo4) != 0, NULL);
    fail_if (im_string_append_str (str, demo3, -1) != str, NULL);
    fail_if (strcmp (im_string_c_str (str), demo5) != 0, NULL);
    fail_if (im_string_prepend_char (str, '-') != str, NULL);
    fail_if (im_string_get_char (str, 0) != '-', NULL);
    fail_if (strcmp (im_string_c_str (str) + 1, demo5) != 0, NULL);
    fail_if (im_string_append_char (str, '-') != str, NULL);
    fail_if (im_string_get_char (str, strlen (demo5) + 1) != '-', NULL);
    fail_if (strncmp (im_string_c_str (str) + 1, demo5, strlen (demo5)) != 0, NULL);
    im_string_assign_static (str, "11");
    im_string_assign_static (other, "--------------------");
    fail_if (im_string_insert (str, 1, other) != str, NULL);
    fail_if (strcmp (im_string_c_str (str), "1--------------------1") != 0, NULL);
    fail_if (im_string_insert_str (str, 11, "1111", -1) != str, NULL);
    fail_if (strcmp (im_string_c_str (str), "1----------1111----------1") != 0, NULL);
    fail_if (im_string_insert_char (str, 13, '-') != str, NULL);
    fail_if (strcmp (im_string_c_str (str), "1----------11-11----------1") != 0, NULL);
    fail_if (im_string_erase (str, 1, 25) != str, NULL);
    fail_if (strcmp (im_string_c_str (str), "11") != 0, NULL);
    fail_if (im_string_prepend_printf (str, "%d", 22) != str, NULL);
    fail_if (strcmp (im_string_c_str (str), "2211") != 0, NULL);
    fail_if (im_string_append_printf (str, "%d", 33) != str, NULL);
    fail_if (strcmp (im_string_c_str (str), "221133") != 0, NULL);
    fail_if (im_string_insert_printf (str, 2, "%d", 44) != str, NULL);
    fail_if (strcmp (im_string_c_str (str), "22441133") != 0, NULL);
    fail_if (im_string_printf (str, "%s", demo5) != str, NULL);
    fail_if (strcmp (im_string_c_str (str), demo5) != 0, NULL);
    im_string_assign_static (str, " abc\tdef ");
    im_string_ascii_toupper (str);
    fail_if (strcmp (im_string_c_str (str), " ABC\tDEF ") != 0, NULL);
    im_string_ascii_tolower (str);
    fail_if (strcmp (im_string_c_str (str), " abc\tdef ") != 0, NULL);
    im_string_ascii_toupper_range (str, 1, 3);
    fail_if (strcmp (im_string_c_str (str), " ABC\tdef ") != 0, NULL);
    im_string_ascii_tolower_range (str, 1, 3);
    fail_if (strcmp (im_string_c_str (str), " abc\tdef ") != 0, NULL);
    im_string_trim_blanks (str);
    fail_if (strcmp (im_string_c_str (str), "abc\tdef") != 0, NULL);
    im_object_unref (str);
}
END_TEST

START_TEST(string_substring)
{
    IMString *str;
    IMString *other;
    IMObjectArray *array;
    str = im_string_new ("Hello world");
    other = im_string_get_sub_string (str, 2, 7);
    fail_if (strcmp (im_string_c_str (other), "llo wor") != 0, NULL);
    im_object_unref (other);
    im_string_assign (str, "inet:127.0.0.1:2345", -1);
    array = im_string_split (str, ":");
    fail_if (im_object_array_size (array) != 3, NULL);
    fail_if (strcmp (im_string_c_str (im_object_array_get (array, 0)), "inet") != 0, NULL);
    fail_if (strcmp (im_string_c_str (im_object_array_get (array, 1)), "127.0.0.1") != 0, NULL);
    fail_if (strcmp (im_string_c_str (im_object_array_get (array, 2)), "2345") != 0, NULL);
    im_object_unref (array);
    im_string_assign (str, "key = value", -1);
    other = im_string_get_left_portion (str, "=");
    fail_if (strcmp (im_string_c_str (other), "key") != 0, NULL);
    im_object_unref (other);
    other = im_string_get_right_portion (str, "=");
    fail_if (strcmp (im_string_c_str (other), "value") != 0, NULL);
    im_object_unref (other);
    im_object_unref (str);
}
END_TEST

Suite *
string_suite (void)
{
    Suite *s;
    TCase *tc;

    s = suite_create ("string");

    tc = tcase_create ("new");
    suite_add_tcase (s, tc);
    tcase_add_test (tc, string_new);
    tcase_add_test (tc, string_new_static);
    tcase_add_test (tc, string_new_length);
    tcase_add_test (tc, string_new_reserved);
    tcase_add_test (tc, string_new_from_printf);
    tcase_add_test (tc, string_miscs);
    tcase_add_test (tc, string_assign);
    tcase_add_test (tc, string_modification);
    tcase_add_test (tc, string_substring);
    tcase_set_timeout (tc, 100);

    return s;
}

// vi:ts=4:sw=4:nowrap:cin:expandtab
